﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Dry.DbInterpreter;
using System.IO;

namespace Dry.Generators
{
    public class IPGenerator : GeneratorBase
    {
        private static string _tablePrefix;

        public static GeneratorFeedback CreateFile(string strTableName)
        {
            return CreateFile(strTableName, "tbl");
        }

        public static GeneratorFeedback CreateFile(string strTableName, string tablePrefix)
        {
            GeneratorFeedback generatorFeedback = new GeneratorFeedback();

            _tablePrefix = tablePrefix;

            string strCode = GetIPClass(strTableName);
            generatorFeedback.Exception = CreateFileFromString("IP\\AutoGenerated\\" + strTableName.Substring(tablePrefix.Length, strTableName.Length - tablePrefix.Length) + "IP.cs", strCode);
            generatorFeedback.Lines = CountLinesInString(strCode);

            return generatorFeedback;
        }

        public static void CreateBaseIP()
        {
            string strCode = Templates.BaseIP.GetBaseDAL().Replace("¤ProjectName¤", Dry.ProjectName);
            CreateFileFromString("IP\\BaseIP.cs", strCode);
        }

        public static string GetIPClass(string strTableName)
        {
            string strCode = String.Empty;
            DbTable dbTable = new DbTable(strTableName, _tablePrefix);

            strCode += GetFileHeader(Dry.ProjectName, "", "", "", _tablePrefix, "");

            strCode += "using System;" + _strNewLine;
            strCode += "using System.Collections.Generic;" + _strNewLine;
            strCode += "using System.Text;" + _strNewLine;
            strCode += _strNewLine;
            strCode += "namespace " + Dry.ProjectName + ".IP" + _strNewLine;
            strCode += "{" + _strNewLine;
            strCode += "    [Serializable]" + _strNewLine;
            strCode += "    public partial class " + dbTable.ClassName + "IP : BaseIP" + _strNewLine;
            strCode += "    {" + _strNewLine;
            

            // Properties
            foreach (DbColumn dbColumn in dbTable.DbColumns)
            {
                // Add property =
                strCode += GetIPProperty(strCode, dbColumn, "");

                // Add extra for datetime columns
                if (GetCodeTypeFromDbType(dbColumn.DataType) == "DateTime")
                {
                    strCode += GetIPProperty(strCode, dbColumn, "_Date");
                    strCode += GetIPProperty(strCode, dbColumn, "_Time");
                }

                // Add prpoperty IN
                if (dbColumn.ShouldHaveInParameters())
                {
                    strCode += GetIPProperty(strCode, dbColumn, "_In", true);
                }

                // Add property NOT IN
                if (dbColumn.ShouldHaveInParameters())
                {
                    strCode += GetIPProperty(strCode, dbColumn, "_NotIn", true);
                }
                  
                // Add property <= and =>
                if (dbColumn.ShouldHaveFromAndToParameters())
                {
                    // Obsolete
                    strCode += "" + _strNewLine;
                    strCode += GetIPProperty(strCode, dbColumn, "_From", false, true, "_LesserOrEqualThan");
                    strCode += GetIPProperty(strCode, dbColumn, "_To", false, true, "_GreaterOrEqualThan");
                    strCode += "" + _strNewLine;

                    // Replaces old
                    strCode += GetIPProperty(strCode, dbColumn, "_LesserThan");
                    strCode += GetIPProperty(strCode, dbColumn, "_GreaterThan");
                    strCode += GetIPProperty(strCode, dbColumn, "_LesserOrEqualThan");
                    strCode += GetIPProperty(strCode, dbColumn, "_GreaterOrEqualThan");

                    // Add extra for datetime columns
                    if(GetCodeTypeFromDbType(dbColumn.DataType) == "DateTime")
                    {
                        // Obsolete
                        strCode += "" + _strNewLine;
                        strCode += GetIPProperty(strCode, dbColumn, "_Date_From", false, true, "_Date_LesserOrEqualThan");
                        strCode += GetIPProperty(strCode, dbColumn, "_Date_To", false, true, "_Date_GreaterOrEqualThan");

                        strCode += GetIPProperty(strCode, dbColumn, "_Time_From", false, true, "_Time_LesserOrEqualThan");
                        strCode += GetIPProperty(strCode, dbColumn, "_Time_To", false, true, "_Time_GreaterOrEqualThan");
                        strCode += "" + _strNewLine;

                        // Replaces old
                        strCode += GetIPProperty(strCode, dbColumn, "_Date_LesserThan");
                        strCode += GetIPProperty(strCode, dbColumn, "_Date_GreaterThan");
                        strCode += GetIPProperty(strCode, dbColumn, "_Date_LesserOrEqualThan");
                        strCode += GetIPProperty(strCode, dbColumn, "_Date_GreaterOrEqualThan");
                        strCode += "" + _strNewLine;

                        strCode += GetIPProperty(strCode, dbColumn, "_Time_LesserThan");
                        strCode += GetIPProperty(strCode, dbColumn, "_Time_GreaterThan");
                        strCode += GetIPProperty(strCode, dbColumn, "_Time_LesserOrEqualThan");
                        strCode += GetIPProperty(strCode, dbColumn, "_Time_GreaterOrEqualThan");
                    }
                }

                // Add property LIKE '%input%', 'input%' and '%input'
                if (dbColumn.ShouldHaveLikeParameters())
                {
                    strCode += GetIPProperty(strCode, dbColumn, "_Like");
                    strCode += GetIPProperty(strCode, dbColumn, "_Like_Start");
                    strCode += GetIPProperty(strCode, dbColumn, "_Like_End");
                    strCode += GetIPProperty(strCode, dbColumn, "_Not");
                }

                // Add property ISNULL
                if (dbColumn.IsNullable)
                {
                    strCode += "        public bool? " + dbColumn.ColumnName + "_IsNull { get; set; }" + _strNewLine;
                }

                strCode += "" + _strNewLine;
            }

            // Add IP constructor
            if (strCode.Contains("public bool? Deleted"))
            {
                strCode += _strNewLine;
                strCode += "        public " + dbTable.ClassName + "IP()" + _strNewLine;
                strCode += "        {" + _strNewLine;
                strCode += "            Deleted = false;" + _strNewLine;
                strCode += "        }" + _strNewLine;
            }

            /*
            strCode += "        public List<SortOrderType> OrderBy = new List<SortOrderType>();" + _strNewLine;
            strCode += "        " + _strNewLine;
            strCode += "        public enum SortOrderType" + _strNewLine;
            strCode += "        {" + _strNewLine;
            foreach (DbColumn dbColumn in dbTable.DbColumns)
            {
                strCode += "            " + dbColumn.ColumnName + "_ASC," + _strNewLine;
                strCode += "            " + dbColumn.ColumnName + "_DESC," + _strNewLine;
            }
            strCode = strCode.Substring(0, strCode.Length - 3) + _strNewLine;
            strCode += "        }" + _strNewLine;
             */

            strCode += "    }" + _strNewLine;
            strCode += "}" + _strNewLine;

            return strCode;
        }


        private static string GetIPProperty(string strCode, DbColumn dbColumn, string strSuffix)
        {
            return GetIPProperty(strCode, dbColumn, strSuffix, false, false, "");
        }

        private static string GetIPProperty(string strCode, DbColumn dbColumn, string strSuffix, bool blnIsListParameter)
        {
            return GetIPProperty(strCode, dbColumn, strSuffix, blnIsListParameter, false, "");
        }

        private static string GetIPProperty(string strCode, DbColumn dbColumn, string strSuffix, bool blnIsListParameter, bool isObsolete, string replacedWith)
        {
            strCode = "";

            if (isObsolete)
                strCode += "        [Obsolete(\"Replaced with " + dbColumn.ColumnName + "_" + replacedWith + "\")] public ";
            else
                strCode += "        public ";

            if (blnIsListParameter)
                strCode += "List<";                        
            strCode += GetCodeTypeFromDbType(dbColumn.DataType);
            if (blnIsListParameter)
            {
                strCode += "> ";
            }
            if (!blnIsListParameter)
            {
                if (dbColumn.DataType == "nvarchar" || dbColumn.DataType == "nchar" || dbColumn.DataType == "binary" || dbColumn.DataType == "varbinary")
                    strCode += " ";
                else
                    strCode += "? ";
            }

            //if (blnIsListParameter)
            //    strCode += dbColumn.ColumnName + strSuffix + ";" + _strNewLine;
            //else
                strCode += dbColumn.ColumnName + strSuffix + " { get; set; }" + _strNewLine;

            return strCode;
        }
    }
}
